package com.client.service.impl;

import com.Emplyment.entity.Article;
import com.Emplyment.util.CacheHotCompany;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.client.mapper.ArticleMapper;
import com.client.service.ClientFirstPageService;
import com.client.mapper.ClientFirstPageMapper;
import com.client.util.CompanyCallable;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ClientFirstPageServiceImpl implements ClientFirstPageService {

    @Autowired
    private ClientFirstPageMapper clientFirstPageMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private static final String COMPANY_HOT_DATA = "company:ZSET:rank";

    private static final String companyHASH_KEY = "company:HASH:data";

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * 获取广告栏图片
     * @return
     */
    @Override
    public List<String> getAdvertisement() {
        List<String> advertisement = clientFirstPageMapper.getAdvertisement();
        return advertisement;
    }

    /**
     * 获取所有公司招聘信息
     * @return
     */
    @Override
    public List<Map<String, String>> getEmployment() {
        List<Map<String, String>> employment = new ArrayList<>();

        if (Boolean.TRUE.equals(redisTemplate.hasKey(COMPANY_HOT_DATA)) && Boolean.TRUE.equals(redisTemplate.hasKey(companyHASH_KEY))) {
            Set set = redisTemplate.opsForZSet().reverseRange(COMPANY_HOT_DATA, 0, 8);
            for (Object id : set) {
                String companyId = (String) id;
                log.info("companyId:{}", companyId);
                String companyData = (String) redisTemplate.opsForHash().get(companyHASH_KEY, companyId);
                if (companyData == null){
                    continue;
                }
                CacheHotCompany cacheHotCompany = JSONObject.parseObject(companyData, new TypeReference<CacheHotCompany>() {
                });
                log.info("cacheHotCompany:{}", cacheHotCompany);
                Long expireAt = cacheHotCompany.getExpireAt();
                Article company = cacheHotCompany.getCompany();
                Map<String, String> map = new HashMap<>();
                map.put("empId", company.getId().toString());
                map.put("empName", company.getTitle());
                map.put("empImgUrl", company.getCoverImg());
                employment.add(map);
                //判断值是否过期
                // 1. 获取当前时间的毫秒时间戳
                long currentTime = System.currentTimeMillis();
                if (currentTime > expireAt) {
                    //如果当前时间大于过期时间，则过期了、加锁然后更新缓存
                    //2. 加锁
                    RLock lock = redissonClient.getLock("LOCK_COMPANY_UPDATE:" + companyId);
                    try {
                        // 尝试非阻塞获取锁（等待0秒，锁持有30秒）
                        boolean isLocked = lock.tryLock(0, 30, TimeUnit.SECONDS);
                        //TODO:线程锁释放的问题
                        if (isLocked) {
                            CompanyCallable companyCallable = new CompanyCallable(articleMapper,redisTemplate,Integer.getInteger(companyId));
                            FutureTask<String> futureTask = new FutureTask<>(companyCallable);
                            taskExecutor.execute(futureTask);
                        }
                    } catch (Exception e) {
                        Thread.currentThread().interrupt();
                    }finally {
                        // 确保锁在异步任务中释放
                        if (lock.isHeldByCurrentThread()) {
                            lock.unlock();
                        }
                    }
                }

            }

        } else {
            List<Article> allEmplyee = articleMapper.getAllEmplyee();
            for (Article article : allEmplyee) {
                Map<String, String> map = new HashMap<>();
                map.put("empId", article.getId().toString());
                map.put("empName", article.getTitle());
                map.put("empImgUrl", article.getCoverImg());
                employment.add(map);

                CacheHotCompany cacheHotCompany = new CacheHotCompany();
                long expireTime = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(2);
                cacheHotCompany.setExpireAt(expireTime);
                cacheHotCompany.setCompany(article);
                redisTemplate.opsForHash().put(companyHASH_KEY,article.getId().toString(), JSONObject.toJSONString(cacheHotCompany));
            }
        }
        return employment;
    }
}
